package com.project.biz.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.biz.CmsProductBiz;
import com.project.biz.CmsProductSkuBiz;
import com.project.biz.CmsShoppingCartBiz;
import com.project.biz.CmsShoppingCartProductSkuBiz;
import com.project.common.enums.LockEnum;
import com.project.common.exception.ServiceException;
import com.project.entity.CmsProduct;
import com.project.entity.CmsProductSku;
import com.project.entity.CmsShoppingCart;
import com.project.mapper.CmsShoppingCartMapper;
import com.project.pojo.dto.UserShoppingCartDTO;
import com.project.pojo.dto.UserShoppingCartItemDTO;
import com.project.pojo.model.AddShoppingCartModel;
import com.project.pojo.model.DelShoppingCartModel;
import com.project.pojo.model.UpdateShoppingCartCountModel;
import com.project.pojo.model.UpdateShoppingCartSkuModel;
import com.project.redis.RedisClient2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: 购物车业务层接口实现类
 * @Author: zhuchi
 * @CreateDate: 2020/10/15 22:42
 * @Version: 1.0
 */
@Slf4j
@Service
public class CmsShoppingCartBizImpl extends ServiceImpl<CmsShoppingCartMapper, CmsShoppingCart> implements CmsShoppingCartBiz {

    /**
     * 商品业务层接口类
     */
    @Autowired
    private CmsProductBiz productBiz;

    /**
     * 商品SKU业务层接口类
     */
    @Autowired
    private CmsProductSkuBiz productSkuBiz;

    /**
     * Redis服务
     */
    @Autowired
    private RedisClient2 redisClient2;

    /**
     * 购物车产品SKU业务层接口类
     */
    @Autowired
    private CmsShoppingCartProductSkuBiz shoppingCartProductSkuBiz;

    /**
     * 添加购物车
     * @param addShoppingCartModel
     * @param userId
     * @return
     */
    @Transactional(rollbackFor = Exception.class , isolation = Isolation.REPEATABLE_READ, timeout = 30)
    public int addShoppingCart(AddShoppingCartModel addShoppingCartModel, Long userId){
        int result = 0;
        //验证商品信息
        CmsProduct product = this.productBiz.getById(addShoppingCartModel.getProductId());
        if (null == product){
            throw new ServiceException("商品不存在");
        }else if (product.getState() == 0){//状态（0:下架,1:上架）
            throw new ServiceException("商品已下架");
        }else if (product.getStatus() == -1){//删除标志（-1:删除,1:正常）
            throw new ServiceException("商品不存在");
        }

        //添加购物车分布式锁
        String addShoppingCart_lock = LockEnum.ADD_SHOPPING_CART_LOCK.Value()+ addShoppingCartModel.getSkuId() ;
        //超时时间（15秒）
        Long expires = System.currentTimeMillis() + Long.parseLong(LockEnum.LOCK_EXPIRES.Value());
        //商品SKU加锁
        if (this.redisClient2.lock(addShoppingCart_lock, String.valueOf(expires))){
            try {
                //验证规格信息
                CmsProductSku productSku = this.productSkuBiz.getById(addShoppingCartModel.getSkuId());
                if (null == productSku){
                    throw new ServiceException("该规格已下架");
                }else if (productSku.getStock() < addShoppingCartModel.getCount()){
                    throw new ServiceException("库存不足");
                }

                Date nowTime = new Date();
                //验证是否加入过该商品
                CmsShoppingCart shoppingCart = this.selectShoppingCartByProductId(addShoppingCartModel.getProductId(), addShoppingCartModel.getSkuId(), userId);
                //如果加入过时再添加只更新数量
                if (null != shoppingCart){
                    shoppingCart.setCount(shoppingCart.getCount() + addShoppingCartModel.getCount());
                    shoppingCart.setUpdateTime(nowTime);
                    result = this.baseMapper.updateById(shoppingCart);
                }else {
                    shoppingCart = new CmsShoppingCart();
                    BeanUtils.copyProperties(addShoppingCartModel, shoppingCart);
                    shoppingCart.setBaseUserId(userId);
                    shoppingCart.setCreateTime(nowTime);
                    shoppingCart.setUpdateTime(nowTime);
                    result = this.baseMapper.insert(shoppingCart);
                    if (result > 0){
                        //添加购物车产品SKU
                        int addShoppingCartProductSku = this.shoppingCartProductSkuBiz.addShoppingCartProductSku(shoppingCart.getCartId(), productSku);
                        log.info("商品加入购物车后,添加购物车产品SKU执行状态：{}", addShoppingCartProductSku);
                    }
                }
            }catch (Exception e){
                log.info("添加购物车时发生异常,参数信息:{},异常信息：{}", addShoppingCartModel, e.getMessage());
                throw new ServiceException(e.getMessage());
            }finally {
                //解锁
                this.redisClient2.unlock(addShoppingCart_lock, String.valueOf(expires));
            }
        }else {
            throw new ServiceException("购买人数较多,请稍后再试");
        }

        return result;
    }

    /**
     * 验证用户是否加入过相同商品,相同规格,如果加入过时再添加只更新数量
     * @param productId
     * @param skuId
     * @param userId
     * @return
     */
    public CmsShoppingCart selectShoppingCartByProductId(Long productId, Long skuId, Long userId){
        QueryWrapper<CmsShoppingCart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("base_user_id", userId);
        queryWrapper.eq("product_id", productId);
        queryWrapper.eq("sku_id", skuId);
        return this.baseMapper.selectOne(queryWrapper);
    }

    /**
     * 修改购物车商品规格
     * @param updateShoppingCartSkuModel
     * @return
     */
    public int updateShoppingCartSku(UpdateShoppingCartSkuModel updateShoppingCartSkuModel){
        CmsShoppingCart shoppingCart = this.baseMapper.selectById(updateShoppingCartSkuModel.getCartId());
        if (null == shoppingCart){
            throw new ServiceException("购物车信息不存在");
        }
        //验证规格信息
        CmsProductSku productSku = this.productSkuBiz.getById(updateShoppingCartSkuModel.getSkuId());
        if (null == productSku){
            throw new ServiceException("该规格已下架");
        }
        shoppingCart.setSkuId(updateShoppingCartSkuModel.getSkuId());
        shoppingCart.setUpdateTime(new Date());
        return this.baseMapper.updateById(shoppingCart);
    }

    /**
     * 修改购物车商品数量
     * @param updateShoppingCartCountModel
     * @return
     */
    public int updateShoppingCartCount(UpdateShoppingCartCountModel updateShoppingCartCountModel){
        CmsShoppingCart shoppingCart = this.baseMapper.selectById(updateShoppingCartCountModel.getCartId());
        if (null == shoppingCart){
            throw new ServiceException("购物车信息不存在");
        }
        //验证规格信息
        CmsProductSku productSku = this.productSkuBiz.getById(shoppingCart.getSkuId());
        if (null == productSku){
            throw new ServiceException("该规格已下架");
        }else if (productSku.getStock() < updateShoppingCartCountModel.getCount()){
            throw new ServiceException("库存不足");
        }
        shoppingCart.setCount(updateShoppingCartCountModel.getCount());
        shoppingCart.setUpdateTime(new Date());
        return this.baseMapper.updateById(shoppingCart);
    }

    /**
     * 获取购物车信息
     * @param userId
     * @return
     */
    public UserShoppingCartDTO getUserShoppingCart(Long userId){
        UserShoppingCartDTO userShoppingCartDTO = new UserShoppingCartDTO();
        //有效商品
        List<UserShoppingCartItemDTO> effectiveProduct = new ArrayList<>();
        //失效商品
        List<UserShoppingCartItemDTO> invalidProduct = new ArrayList<>();
        //获取用户购物车商品数据
        List<UserShoppingCartItemDTO> userShoppingCartItemDTOS = this.baseMapper.getUserShoppingCart(userId);
        if (null != userShoppingCartItemDTOS && userShoppingCartItemDTOS.size() > 0){
            for (UserShoppingCartItemDTO userShoppingCartItemDTO : userShoppingCartItemDTOS){
                if (userShoppingCartItemDTO.getProductState() == 1){
                    effectiveProduct.add(userShoppingCartItemDTO);
                }else {
                    invalidProduct.add(userShoppingCartItemDTO);
                }
            }
        }
        userShoppingCartDTO.setEffectiveProduct(effectiveProduct);
        userShoppingCartDTO.setInvalidProduct(invalidProduct);

        return userShoppingCartDTO;
    }

    /**
     * 删除购物车商品
     * @param delShoppingCartModel
     * @param userId
     * @return
     */
    public int delUserShoppingCart(DelShoppingCartModel delShoppingCartModel, Long userId){
        QueryWrapper<CmsShoppingCart> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("cart_id", delShoppingCartModel.getCartIds());
        List<CmsShoppingCart> list = this.baseMapper.selectList(queryWrapper);
        int result = 0;
        if (null != list && list.size() > 0){
            for (CmsShoppingCart cmsShoppingCart : list){
                //只能删除自己购物车的商品
                if (cmsShoppingCart.getBaseUserId().equals(userId)){
                    //根据购物车ID删除购物车产品SKU
                    int delShoppingCartProductSku = this.shoppingCartProductSkuBiz.delShoppingCartProductSku(cmsShoppingCart.getCartId());
                    log.info("根据购物车ID删除购物车产品SKU,执行结果:{}", delShoppingCartProductSku);
                    int delState = this.baseMapper.deleteById(cmsShoppingCart);
                    if (delState > 0){
                        result++;
                    }
                }
            }
        }

        return result;
    }

}
